/**
 * EventSource polyfill for uni-app
 * Implements Server-Sent Events (SSE) functionality for streaming responses
 */

class EventSource {
  constructor(url, options = {}) {
    this.url = url;
    this.options = options;
    this.readyState = EventSource.CONNECTING;
    this.onopen = null;
    this.onmessage = null;
    this.onerror = null;
    
    // Custom event listeners
    this.eventListeners = {};
    
    // Initialize connection
    this.connect();
  }
  
  connect() {
    try {
      // Using uni.request with streaming capability
      this.requestTask = uni.request({
        url: this.url,
        method: 'GET',
        header: this.options.headers || {},
        // Enable streaming response
        enableChunked: true,
        success: (res) => {
          this.readyState = EventSource.OPEN;
          if (typeof this.onopen === 'function') {
            this.onopen({ type: 'open' });
          }
          
          // Process the response data
          this.processResponse(res.data);
        },
        fail: (err) => {
          this.readyState = EventSource.CLOSED;
          if (typeof this.onerror === 'function') {
            this.onerror({ type: 'error', data: err });
          }
        }
      });
    } catch (error) {
      this.readyState = EventSource.CLOSED;
      if (typeof this.onerror === 'function') {
        this.onerror({ type: 'error', data: error });
      }
    }
  }
  
  processResponse(data) {
    // Parse SSE format data
    if (typeof data === 'string') {
      const lines = data.split('\n');
      let eventData = '';
      let eventType = 'message';
      
      for (const line of lines) {
        if (line.startsWith('data: ')) {
          const dataContent = line.substring(6); // Remove 'data: ' prefix
          eventData += dataContent + '\n';
        } else if (line.startsWith('event: ')) {
          eventType = line.substring(7); // Remove 'event: ' prefix
        } else if (line.startsWith('id: ')) {
          // Event ID - could be used for reconnection
        } else if (line.startsWith('retry: ')) {
          // Retry time - could be used for reconnection
        } else if (line === '') {
          // End of event
          if (eventData) {
            // Remove trailing newline
            eventData = eventData.trim();
            
            // Dispatch event
            if (eventType === 'message' && typeof this.onmessage === 'function') {
              this.onmessage({ type: 'message', data: eventData });
            } else if (this.eventListeners[eventType]) {
              this.eventListeners[eventType].forEach(listener => {
                listener({ type: eventType, data: eventData });
              });
            }
            
            // Reset for next event
            eventData = '';
            eventType = 'message';
          }
        }
      }
    }
  }
  
  addEventListener(type, listener) {
    if (!this.eventListeners[type]) {
      this.eventListeners[type] = [];
    }
    this.eventListeners[type].push(listener);
  }
  
  removeEventListener(type, listener) {
    if (this.eventListeners[type]) {
      const index = this.eventListeners[type].indexOf(listener);
      if (index > -1) {
        this.eventListeners[type].splice(index, 1);
      }
    }
  }
  
  close() {
    this.readyState = EventSource.CLOSED;
    if (this.requestTask) {
      this.requestTask.abort();
    }
  }
}

// Ready states
EventSource.CONNECTING = 0;
EventSource.OPEN = 1;
EventSource.CLOSED = 2;

export default EventSource;